﻿using System.Collections;
using System.Collections.Generic;

namespace exercise.链表
{
    public class ListNode<T>
    {
        public T Value { get; set; }
        public ListNode<T> Next { get; set; }
        public ListNode<T> Previous { get; set; }


        public ListNode(T value)
        {
            Value = value;
            Next = null;
        }
    }

    //双向循环链表
    public class LinkedList<T> : IEnumerable<T>
    {
        public ListNode<T> Head { get; private set; }
        public ListNode<T> Tail { get; private set; }
        public int Count { get; private set; }

        public LinkedList()
        {
            Head = Tail = null;
            Count = 0;
        }

        public ListNode<T> ReverseList()
        {

            return null;
        }


        public void Add(T value)
        {
            ListNode<T> node = new ListNode<T>(value);
            if (Head == null)
            {
                Head = node;
                Tail = node;
                Head.Next = Head;
                Head.Previous = Head;
            }
            else
            {
                node.Previous = Tail;
                node.Next = Head;
                Tail.Next = node;
                Head.Previous = node;
                Tail = node;
            }
            Count++;
        }

        public bool Remove(T value)
        {
            ListNode<T> current = Head;
            if (current == null) return false;
            ListNode<T> previous = null;

            do
            {
                if (current.Value.Equals(value))
                {
                    if (current == Head)
                    {
                        Head = Head.Next;
                        Tail.Next = Head;
                        Head.Previous = Tail;
                    }
                    else if (current == Tail)
                    {
                        Tail = Tail.Previous;
                        Tail.Next = Head;
                        Head.Previous = Tail;
                    }
                    else
                    {
                        current.Previous.Next = current.Next;
                        current.Next.Previous = current.Previous;
                    }

                    if (Head == Tail && Head.Value.Equals(value))
                    {
                        Head = null;
                        Tail = null;
                    }

                    return true;
                }
                current = current.Next;
            } while (current != Head);

            return false;
        }

        public ListNode<T> Find(T value)
        {
            ListNode<T> current = Head;
            while (current != null)
            {
                if (current.Value.Equals(value))
                {
                    return current;
                }
                current = current.Next;
            }
            return null;
        }

        public bool Contains(T value)
        {
            ListNode<T> current = Head;
            while (current != null)
            {
                if (current.Value.Equals(value))
                {
                    return true;
                }
                current = current.Next;
            }
            return false;
        }

        public void Clear()
        {
            Head = Tail = null;
            Count = 0;
        }

        /// <summary>
        /// 返回一个迭代器
        /// </summary>
        /// <returns></returns>
        public IEnumerator<T> GetEnumerator()
        {
            ListNode<T> current = Head;
            if (current != null)
            {
                do
                {
                    yield return current.Value;
                    current = current.Next;
                } while (current != Head);
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        //System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        //{
        //    return GetEnumerator();
        //}
    }
}
